<template>
    <div class="ai-chat-container">
        <!-- 头部区域 -->
        <div class="ai-chat-header">
            <div class="ai-chat-title">
                <span class="ai-icon">🤖</span>
                <h2>AI助手</h2>
            </div>
            <div class="ai-chat-actions">
                <a-tooltip placement="bottom">
                    <template #title>清空对话</template>
                    <button class="btn btn-light" @click="clearChat">
                        <span class="icon">🧹</span>
                    </button>
                </a-tooltip>
                <a-popover title="对话历史记录" trigger="click" placement="bottomRight">
                    <template #content>
                        <div style="width: 400px; max-height: 250px; overflow-y: auto;">
                            <!-- 显示加载动画 -->
                            <div v-if="historyLoading" class="flex justify-center items-center py-8">
                                <loading2 />
                            </div>
                            
                            <!-- 加载完成后显示内容 -->
                            <div v-else>
                                <div v-if="formateHistoryList.size === 0" class="text-center text-gray-500 py-4">
                                    暂无历史对话记录
                                </div>
                                <div v-else class="space-y-3">
                                    <div v-for="([chatId, chatItems], index) in Array.from(formateHistoryList.entries())" :key="chatId" @click="getCurChat(chatId)">
                                        <a-tooltip placement="top" >
                                            <div class="p-2 border rounded hover:bg-opacity-10 hover:bg-white cursor-pointer">
                                                <div class="font-medium text-sm truncate" :title="getUserQuestion(chatItems)">
                                                    👤 {{ getUserQuestion(chatItems) || '未知问题' }}
                                                </div>
                                                <div class="text-xs text-gray-400 mt-1">
                                                    对话ID: {{ chatId }} • {{ formatTimeFromData(getLatestTime(chatItems)) }}
                                                </div>
                                            </div>
                                        </a-tooltip>
                                    </div>
                                    <a-pagination 
                                        v-model:current="tableParams.page"
                                        v-model:page-size="tableParams.pageSize" 
                                        :total="tableParams.total"
                                        show-less-items 
                                        @change="handlePagChange"
                                        @showSizeChange="handlePagChange"
                                    />
                                </div>
                            </div>
                        </div>
                    </template>
                    <button class="btn btn-light" @click="getHistoryList">
                        <span class="icon">📊</span>
                    </button>
                </a-popover>
            </div>
        </div>

        <!-- 聊天内容区域 -->
        <div class="ai-chat-messages" ref="messagesContainer" @scroll="onScroll">
            <!-- 欢迎消息 -->
            <div v-if="messages.length === 0" class="welcome-message">
                <div class="welcome-icon">👋</div>
                <h3>你好！我是你的AI助手</h3>
                <p>有什么我可以帮助你的吗？</p>
            </div>
            <!-- 消息列表 -->
            <div v-for="(message, index) in messages" :key="index" :class="['message-wrapper', message.role]">
                <div class="message-avatar">{{ message.role === 'user' ? '👤' : '🤖' }}</div>
                <div class="message-content">
                    <div class="message-bubble" :class="message.role">
                        <!-- 根据是否在流式输出显示不同内容 -->
                        <div v-if="message.isStreaming && !(message.streamingContent && message.streamingContent.trim())" class="thinking-indicator">
                            <div class="thinking-text">思考中...</div>
                            <!-- <div class="thinking-dots">
                                <span class="thinking-dot"></span>
                                <span class="thinking-dot"></span>
                                <span class="thinking-dot"></span>
                            </div> -->
                        </div>
                        <div v-else 
                            class="message-text"
                            v-html="message.isStreaming ? formatMessage(message.streamingContent || '') : formatMessage(message.content)"
                        ></div>
                        <!-- 只有当有内容时才显示时间戳 -->
                        <div v-if="!(message.isStreaming && !(message.streamingContent && message.streamingContent.trim()))" class="message-time">{{ message.timestamp }}</div>
                    </div>
                </div>
            </div>

            <!-- 加载动画 -->
            <div v-if="isLoading" class="loading-wrapper">
                <div class="loading-indicator">
                    <span class="loading-dot"></span>
                    <span class="loading-dot"></span>
                    <span class="loading-dot"></span>
                </div>
            </div>
        </div>

        <!-- 输入区域 -->
        <div class="ai-chat-input">
            <div class="input-container">
                <textarea v-model="inputMessage" @keydown.enter.prevent="handleEnterKey" placeholder="输入你的问题..."
                    class="message-input" :disabled="isLoading" rows="1" ref="messageInput"></textarea>
                <div class="input-actions">
                    <button class="btn btn-send" @click="sendMessage" :disabled="!inputMessage.trim() || isLoading">
                        <span class="send-icon">➤</span>
                    </button>
                </div>
            </div>
            <div class="input-hint">
                <small>按 Enter 发送消息，Shift + Enter 换行</small>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts" name="aiAssistant">
import { ChatAiApi, ChatAiStreamApi, GetAiHistoryList, GetChatDetailById } from '@/api/ai';
import type { ResType } from '@/api/types';
import { ref, computed, watch, onMounted, nextTick, useTemplateRef, onBeforeMount } from 'vue';
import {mdIt} from '@/utils/md';
import { getToken } from '@/utils/signalR';
import { showMsg } from '@/utils';
import dayjs from 'dayjs'
import type { TableParamsResType } from '@/views/system/onlineUser/type';
import loading2 from '@/components/loading/loading2.vue';

defineOptions({
    name:"aiAssistant"
})

// 定义消息类型
interface Message {
    role: 'user' | 'assistant';
    content: string;
    timestamp: string;
    isStreaming?: boolean; // 是否正在流式输出
    streamingContent?: string; // 流式输出的临时内容
}

const messageRefs = ref([])
// const setmessageRef = (el) => {
//     if (el) {
//         messageRefs.value[index] = el;
//     }
// };

// 状态定义
const inputMessage = ref('');
const messages = ref<Message[]>([]);
const isLoading = ref(false);
const messagesContainer = ref<HTMLDivElement>();
const messageInput = ref<HTMLTextAreaElement>();
const hasScrolledUp = ref(false);
const tableParams = ref({
    page:1,
    pageSize:3,
    total:0
})
type ChatItem ={
    content:string 
    chatRole:string 
    chatId:any
}
const historyList = ref<ChatItem[]>()
const formateHistoryList = ref<Map<any, ChatItem[]>>(new Map())
const historyLoading = ref(false)

// 生成格式化时间
const formatTime = (time?:any) => {
    return dayjs(time).format('YYYY-MM-DD HH:mm');
};


// 发送消息
const sendMessage = async () => {
    const content = inputMessage.value.trim();
    if (!content || isLoading.value) return;

    // 添加用户消息
    messages.value.push({
        role: 'user',
        content,
        timestamp: formatTime()
    });

    inputMessage.value = '';
    isLoading.value = true;
    hasScrolledUp.value = false;

    // 滚动到底部
    await nextTick();
    scrollToBottom();

    try {
        // 创建AI回答的占位消息
        const aiMessageIndex = messages.value.push({
            role: 'assistant',
            content: '',
            timestamp: formatTime(),
            isStreaming: true,
            streamingContent: ''
        }) - 1;

        // 滚动到底部显示新消息
        await nextTick();
        scrollToBottom();

        // 获取AI回答并实现流式效果
        const fullResponse = await handleQuery(content, aiMessageIndex);
        
        // 流式输出完成，更新最终内容
        messages.value[aiMessageIndex] = {
            ...messages.value[aiMessageIndex],
            role: 'assistant',
            content: fullResponse,
            timestamp: formatTime()
        };
        
    } catch (error) {
        console.error('获取AI回答失败:', error);
        messages.value.push({
            role: 'assistant',
            content: '抱歉，我暂时无法回答你的问题。请稍后再试。',
            timestamp: formatTime()
        });
    } finally {
        isLoading.value = false;
        // 滚动到底部
        await nextTick();
        scrollToBottom();
    }
};

const formatMessage = (content: string): string => {
    if (!content) return '';
    return mdIt.render(content)
};

// 处理回车键
const handleEnterKey = (event: KeyboardEvent) => {
    if (event.shiftKey) {
        // Shift + Enter 换行
        return;
    }
    sendMessage();
};

// 清空对话
const clearChat = () => {
    if (confirm('确定要清空所有对话吗？')) {
        messages.value = [];
        inputMessage.value = '';
    }
};

// 滚动到底部
const scrollToBottom = () => {
    if (messagesContainer.value && !hasScrolledUp.value) {
        messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight;
    }
};

// 监听滚动事件
const onScroll = () => {
    if (messagesContainer.value) {
        const { scrollTop, scrollHeight, clientHeight } = messagesContainer.value;
        hasScrolledUp.value = scrollTop < scrollHeight - clientHeight - 10;
    }
};



// 监听消息变化，自动滚动
watch(messages, async () => {
    await nextTick();
    scrollToBottom();
});

const handleQuery = async (content:string, messageIndex: number)=>{
    try {
        const response = await fetch("/api/ai/chatAiStream",{
            method:"POST",
            body:JSON.stringify({qs:content}),
            headers:{
                'Content-Type': 'application/json',
                Authorization: `Bearer ${getToken()}`,
            }
        });
        
        if (!response.ok) {
            throw new Error(`请求失败: ${response.status}`);
        }
        
        const reader = response.body?.getReader();
        if(!reader){
            showMsg("获取流失败","warning");
            return "无法获取流式响应";
        }
        
        const decoder = new TextDecoder();
        let fullText = '';
        let buffer = '';
        
        // 循环读取流数据
        while (true) {
            const { done, value } = await reader.read();
            
            if (done) {
                break;
            }
            
            // 解码接收到的字节
            buffer += decoder.decode(value, { stream: true });
            fullText = buffer
            messages.value[messageIndex].streamingContent = fullText;
            await nextTick()
            scrollToBottom()
        }
        return fullText;
    } catch (error) {
        console.error('流式请求异常:', error);
        throw error;
    }
};

const getHistoryList = async ()=>{
    historyLoading.value = true
    const res :ResType<TableParamsResType<ChatItem>>= await GetAiHistoryList(tableParams.value);
    if(res.data.code == 200){
        tableParams.value.total = res.data.result.total 
        historyList.value = res.data.result.items
        formateHistoryList.value.clear()
        historyList.value.forEach((item)=>{
            if(!formateHistoryList.value.has(item.chatId)){
                formateHistoryList.value.set(item.chatId,[] as ChatItem[])
            }
            formateHistoryList.value.get(item.chatId)?.push({
                ...item,
                content : JSON.parse(item.content)
            })
        })
    }
    historyLoading.value = false
}


// 获取用户的问题
const getUserQuestion = (chatItems: any[]): string => {
    // 查找用户角色的消息
    const userItem = chatItems.find(item => item.chatRole === 'user');
    return userItem ? userItem.content : '';
};

// 获取AI的回答
const getAssistantReply = (chatItems: any[]): string => {
    // 查找助手角色的消息
    const assistantItem = chatItems.find(item => item.chatRole === 'assistant');
    return assistantItem ? assistantItem.content : '暂无回答';
};

// 获取最新消息的时间
const getLatestTime = (chatItems: any[]): string => {
    if (!chatItems || chatItems.length === 0) return '';
    // 按创建时间排序，取最新的
    const sortedItems = [...chatItems].sort((a, b) => 
        new Date(b.createTime).getTime() - new Date(a.createTime).getTime()
    );
    return sortedItems[0].createTime;
};

// 格式化时间显示
const formatTimeFromData = (timeStr: string): string => {
    if (!timeStr) return '';
    return dayjs(timeStr).format('MM-DD HH:mm');
};

const handlePagChange = async(current: number, pageSize: number)=>{
    tableParams.value.page = current;
    await getHistoryList()
}

const getCurChat = async(chart:string)=>{
    isLoading.value = true
    const res:ResType<any[]> = await GetChatDetailById({id:chart})
    console.log(res.data.result);
    messages.value = res.data.result.map(item=>{
        return {
            role:item.chatRole,
            content:item.content,
            streamingContent:item.content,
            timestamp:formatTime(item.createTime),
            isStreaming:false
        }
    })
    isLoading.value = false
}

onBeforeMount(async()=>{
})

// 组件挂载时的处理
onMounted(async() => {
    // 聚焦到输入框
    messageInput.value?.focus();
});
</script>

<style scoped>
/* 基础样式 - 修改为适应父容器 */
.ai-chat-container {
    display: flex;
    flex-direction: column;
    height: calc(100vh - 180px);
    /* 调整高度以适应现有布局 */
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
}

/* 头部样式 */
.ai-chat-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1rem 2rem;
    background: rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid rgba(255, 255, 255, 0.2);
    color: white;
}

.ai-chat-title {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.ai-icon {
    font-size: 1.5rem;
}

.ai-chat-actions {
    display: flex;
    gap: 0.5rem;
}

.btn {
    padding: 0.5rem;
    border: none;
    border-radius: 0.5rem;
    cursor: pointer;
    transition: all 0.3s ease;
}

.btn-light {
    background: rgba(255, 255, 255, 0.2);
    color: white;
}

.btn-light:hover {
    background: rgba(255, 255, 255, 0.3);
    transform: translateY(-1px);
}

/* 消息区域样式 - 自适应高度 */
.ai-chat-messages {
    flex: 1;
    overflow-y: auto;
    padding: 2rem;
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.3) transparent;
}

.ai-chat-messages::-webkit-scrollbar {
    width: 8px;
}

.ai-chat-messages::-webkit-scrollbar-track {
    background: transparent;
}

.ai-chat-messages::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.3);
    border-radius: 4px;
}

.ai-chat-messages::-webkit-scrollbar-thumb:hover {
    background: rgba(255, 255, 255, 0.5);
}

/* 欢迎消息 */
.welcome-message {
    text-align: center;
    color: white;
    margin-top: 5rem;
}

.welcome-icon {
    font-size: 3rem;
    margin-bottom: 1rem;
}

.welcome-message h3 {
    font-size: 1.5rem;
    margin-bottom: 0.5rem;
}

.welcome-message p {
    color: rgba(255, 255, 255, 0.8);
}

/* 消息样式 */
.message-wrapper {
    display: flex;
    gap: 0.75rem;
    margin-bottom: 1.5rem;
    animation: fadeIn 0.3s ease;
}

.message-wrapper.user {
    justify-content: flex-end;
}

.message-avatar {
    font-size: 1.25rem;
    flex-shrink: 0;
}

.message-wrapper.user .message-avatar {
    order: 2;
}

.message-wrapper.user .message-content {
    order: 1;
}

.message-content {
    max-width: 70%;
}

.message-bubble {
    padding: 0.75rem 1rem;
    border-radius: 1rem;
    position: relative;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

.message-bubble.user {
    background: rgba(255, 255, 255, 0.9);
    color: #333;
    border-bottom-right-radius: 0.25rem;
}

.message-bubble.assistant {
    background: rgba(255, 255, 255, 0.1);
    color: white;
    border-bottom-left-radius: 0.25rem;
}

.message-text {
    line-height: 1.5;
    word-wrap: break-word;
}

.message-time {
    font-size: 0.75rem;
    opacity: 0.7;
    margin-top: 0.25rem;
    text-align: right;
}

/* 加载动画 */
.loading-wrapper {
    display: flex;
    justify-content: flex-start;
    margin: 1rem 0;
    padding-left: 2.5rem;
}

.loading-indicator {
    display: flex;
    gap: 0.25rem;
    align-items: center;
}

.loading-dot {
    width: 0.5rem;
    height: 0.5rem;
    background: white;
    border-radius: 50%;
    animation: pulse 1.4s ease-in-out infinite both;
}

.loading-dot:nth-child(2) {
    animation-delay: -0.32s;
}

.loading-dot:nth-child(3) {
    animation-delay: -0.56s;
}

/* 输入区域样式 */
.ai-chat-input {
    padding: 1rem 2rem;
    background: rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(10px);
    border-top: 1px solid rgba(255, 255, 255, 0.2);
}

.input-container {
    display: flex;
    gap: 0.75rem;
    align-items: flex-end;
}

.message-input {
    flex: 1;
    padding: 0.75rem 1rem;
    border: none;
    border-radius: 0.5rem;
    background: rgba(255, 255, 255, 0.9);
    resize: none;
    font-family: inherit;
    font-size: 1rem;
    outline: none;
    transition: all 0.3s ease;
    min-height: 2.5rem;
    max-height: 8rem;
}

.message-input:focus {
    box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.5);
}

.message-input:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

.btn-send {
    padding: 0.75rem 1.5rem;
    background: linear-gradient(45deg, #4CAF50, #45a049);
    color: white;
    border: none;
    border-radius: 0.5rem;
    cursor: pointer;
    font-weight: bold;
    transition: all 0.3s ease;
    flex-shrink: 0;
}

.btn-send:hover:not(:disabled) {
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(76, 175, 80, 0.4);
}

.btn-send:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.input-hint {
    text-align: center;
    margin-top: 0.5rem;
    color: rgba(255, 255, 255, 0.7);
}

/* 动画效果 */
@keyframes fadeIn {
    from {
        opacity: 0;
        transform: translateY(10px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes pulse {

    0%,
    80%,
    100% {
        transform: scale(0);
        opacity: 0.5;
    }

    40% {
        transform: scale(1);
        opacity: 1;
    }
}

/* 响应式设计 */
@media (max-width: 768px) {
    .ai-chat-container {
        height: calc(100vh - 150px);
        /* 在移动端进一步调整高度 */
    }

    .ai-chat-header {
        padding: 0.75rem 1rem;
    }

    .ai-chat-messages {
        padding: 1rem;
    }

    .ai-chat-input {
        padding: 0.75rem 1rem;
    }

    .message-content {
        max-width: 85%;
    }
}

/* 思考中状态的样式 */
.thinking-indicator {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 0;
}

.thinking-text {
  color: #666;
  font-size: 14px;
}

.thinking-dots {
  display: flex;
  gap: 4px;
}

.thinking-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background-color: #999;
  animation: thinking-animation 1.4s infinite ease-in-out both;
}

.thinking-dot:nth-child(1) {
  animation-delay: -0.32s;
}

.thinking-dot:nth-child(2) {
  animation-delay: -0.16s;
}

@keyframes thinking-animation {
  0%, 80%, 100% {
    transform: scale(0);
  }
  40% {
    transform: scale(1);
  }
}
</style>
